﻿//TODO: Bottomhat: This filter has to be thoroughly tested

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Bottom Hat
    /// The Bottom Hat module performs a dilation routine (grows the current white image), 
    /// followed by an erosion (shrinks the current white image) and then subtracts the original image. 
    /// Dilation followed by erosion will connect objects close to each other. 
    /// Subtracting the original will result in the display of just the connection points between close objects. 
    /// </summary>
    public class BottomHat : BaseForeBackgroundColorFilter
    {
        protected Erode erode = new Erode();
        protected BinaryDilation binaryDilation = new BinaryDilation();
        protected And and = new And();

        /// <summary>
        /// default constructor
        /// </summary>
        public BottomHat()
        {
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_bottomHat"></param>
        internal BottomHat(BottomHat _bottomHat)
        {
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmapDilated = binaryDilation.ExecuteCloned(_bitmap);
            UnsafeBitmap bitmapResult = and.Process(bitmapDilated, _bitmap);
            //bitmapDilated.UnlockImage();

            erode.Execute(bitmapResult);

            BitmapFunctions.Copy(bitmapResult, _bitmap);
            return _bitmap;
        }

        /// <summary>
        /// used to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new BottomHat(this);
        }
    }
}
